package com.pg.auth.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pg.auth.model.dto.sysrolemenu.SysRoleMenuConvertor;
import com.pg.auth.model.dto.sysrolemenu.SysRoleMenuDTO;
import com.pg.auth.model.dto.sysrolemenu.SysRoleMenuReq;
import com.pg.auth.model.dto.sysrolemenu.SysRoleMenuVO;
import com.pg.auth.model.entity.SysRoleMenu;
import com.pg.auth.model.mapper.SysRoleMenuMapper;
import com.pg.auth.service.SysRoleMenuService;
import com.pg.base.component.PageVO;
import com.pg.base.component.Pager;
import com.pg.base.enums.DeleteEnum;
import com.pg.base.vo.LoginVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/***
 * SysRoleMenuServiceImpl
 * @author : huhuaping
 * @Date : 2024-06-06 20:59:34
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SysRoleMenuServiceImpl implements SysRoleMenuService {

    private final SysRoleMenuMapper sysRoleMenuMapper;

    @Override
    public PageVO<SysRoleMenuVO> page(Pager<SysRoleMenuReq, SysRoleMenuVO> pageReq){

        QueryWrapper<SysRoleMenu> queryWrapper = baseQueryWrapper(pageReq.getParam());

        PageVO<SysRoleMenuVO> result = sysRoleMenuMapper.selectPage(pageReq.getPageVO(), queryWrapper);
        return result;
    }

    @Override
    public List<SysRoleMenuVO> list(SysRoleMenuReq sysRoleMenuReq){

        QueryWrapper<SysRoleMenu> queryWrapper = baseQueryWrapper(sysRoleMenuReq);

        List<SysRoleMenu> sysRoleMenuList = sysRoleMenuMapper.selectList(queryWrapper);

        return SysRoleMenuConvertor.INSTANCE.listDbToVO(sysRoleMenuList);

    }

    @Override
    public SysRoleMenuVO getById(Long roleMenuId) {
        SysRoleMenu sysRoleMenu = sysRoleMenuMapper.selectById(roleMenuId);
        return SysRoleMenuConvertor.INSTANCE.dbToVO(sysRoleMenu);
    }

    @Override
    public Long add(SysRoleMenuDTO sysRoleMenuDTO,LoginVO userVo) {
        SysRoleMenu sysRoleMenuAdd = SysRoleMenuConvertor.INSTANCE.dtoToDB(sysRoleMenuDTO);
        sysRoleMenuMapper.insert(sysRoleMenuAdd);
        return sysRoleMenuAdd.getRoleMenuId();
    }

    @Override
    public Integer updateById(SysRoleMenuDTO sysRoleMenuDTO,LoginVO userVo) {
        SysRoleMenu sysRoleMenuAdd = SysRoleMenuConvertor.INSTANCE.dtoToDB(sysRoleMenuDTO);
        int count = sysRoleMenuMapper.updateById(sysRoleMenuAdd);
        return count;
    }

    @Override
    public int deleteById(Long roleMenuId) {
        SysRoleMenu sysRoleMenu = sysRoleMenuMapper.selectById(roleMenuId);

        // 封装对象
        SysRoleMenu sysRoleMenuDelete = new SysRoleMenu();

        sysRoleMenuDelete.setRoleMenuId(roleMenuId);
        sysRoleMenuDelete.setDeleteStatus(DeleteEnum.DELETE.getValue());

        return sysRoleMenuMapper.updateById(sysRoleMenuDelete);

    }



    @Override
    public int save(Long roleId, List<Long> menuIdList, LoginVO loginVO) {

        menuIdList = Optional.ofNullable(menuIdList).orElse(new ArrayList<>());

        // 查询数据库中的关系
        QueryWrapper<SysRoleMenu> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<SysRoleMenu> lambda =  queryWrapper.lambda();
        lambda.eq(SysRoleMenu::getDeleteStatus,DeleteEnum.NORMAL.getValue());
        lambda.eq(SysRoleMenu::getRoleId, roleId);
        List<SysRoleMenu> sysRoleMenus = sysRoleMenuMapper.selectList(queryWrapper);

        List<Long> dbList = sysRoleMenus.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());

        List<Long> addList = menuIdList.stream().filter(item -> !dbList.contains(item)).collect(Collectors.toList());
        List<Long> finalMenuIdList = menuIdList;
        List<Long> delList = dbList.stream().filter(item -> !finalMenuIdList.contains(item)).collect(Collectors.toList());

        // 新增关系
        addList.forEach(item -> {;
            SysRoleMenu sysRoleMenuAdd = new SysRoleMenu();
            sysRoleMenuAdd.setRoleId(roleId);
            sysRoleMenuAdd.setMenuId(item);

            sysRoleMenuAdd.setCreateTime(new Date());
            sysRoleMenuAdd.setDeleteStatus(DeleteEnum.NORMAL.getValue());

            if( ObjectUtil.isNotEmpty(loginVO)) {
                sysRoleMenuAdd.setCreateUser(loginVO.getUserId());
                sysRoleMenuAdd.setCreateUserName(loginVO.getLoginName());
            }
            sysRoleMenuMapper.insert(sysRoleMenuAdd);
        });

        // 删除关系
        if (!delList.isEmpty()) {

            QueryWrapper<SysRoleMenu> delWrapper = new QueryWrapper<>();
            LambdaQueryWrapper<SysRoleMenu> lambda1 =  delWrapper.lambda();
            lambda1.in(SysRoleMenu::getMenuId,delList)
                    .eq(SysRoleMenu::getRoleId,roleId);

            sysRoleMenuMapper.delete(delWrapper);
        }

        log.info("save role menu rel all [{}],add [{}],del [{}]", JSON.toJSONString(menuIdList),JSON.toJSONString(addList),JSON.toJSONString(delList));

        return menuIdList.size();
    }

    @Override
    public List<SysRoleMenuVO> listByRoleId(Long roleId) {

        QueryWrapper<SysRoleMenu> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<SysRoleMenu> lambda =  queryWrapper.lambda();
        lambda.eq(SysRoleMenu::getDeleteStatus,DeleteEnum.NORMAL.getValue());
        lambda.eq(SysRoleMenu::getRoleId, roleId);

        List<SysRoleMenu> roleMenuList = sysRoleMenuMapper.selectList(queryWrapper);

        return SysRoleMenuConvertor.INSTANCE.listDbToVO(roleMenuList);

    }


    private QueryWrapper<SysRoleMenu> baseQueryWrapper(SysRoleMenuReq sysRoleMenu) {
        QueryWrapper<SysRoleMenu> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<SysRoleMenu> lambda =  queryWrapper.lambda();
        lambda.eq(SysRoleMenu::getDeleteStatus,DeleteEnum.NORMAL.getValue());
            lambda.orderByDesc(SysRoleMenu::getRoleMenuId);
        if (ObjectUtil.isNotEmpty(sysRoleMenu.getRoleMenuId())) {
            lambda.eq(SysRoleMenu::getRoleMenuId, sysRoleMenu.getRoleMenuId());
        }
        if (ObjectUtil.isNotEmpty(sysRoleMenu.getRoleId())) {
            lambda.eq(SysRoleMenu::getRoleId, sysRoleMenu.getRoleId());
        }
        if (ObjectUtil.isNotEmpty(sysRoleMenu.getMenuId())) {
            lambda.eq(SysRoleMenu::getMenuId, sysRoleMenu.getMenuId());
        }
        if (ObjectUtil.isNotEmpty(sysRoleMenu.getCreateUser())) {
            lambda.eq(SysRoleMenu::getCreateUser, sysRoleMenu.getCreateUser());
        }
        if (ObjectUtil.isNotEmpty(sysRoleMenu.getCreateUserName())) {
            lambda.eq(SysRoleMenu::getCreateUserName, sysRoleMenu.getCreateUserName());
        }
        if (ObjectUtil.isNotEmpty(sysRoleMenu.getCreateTime())) {
            lambda.eq(SysRoleMenu::getCreateTime, sysRoleMenu.getCreateTime());
        }
        if (ObjectUtil.isNotEmpty(sysRoleMenu.getUpdateUser())) {
            lambda.eq(SysRoleMenu::getUpdateUser, sysRoleMenu.getUpdateUser());
        }
        if (ObjectUtil.isNotEmpty(sysRoleMenu.getUpdateUserName())) {
            lambda.eq(SysRoleMenu::getUpdateUserName, sysRoleMenu.getUpdateUserName());
        }
        if (ObjectUtil.isNotEmpty(sysRoleMenu.getUpdateTime())) {
            lambda.eq(SysRoleMenu::getUpdateTime, sysRoleMenu.getUpdateTime());
        }
        if (ObjectUtil.isNotEmpty(sysRoleMenu.getDeleteStatus())) {
            lambda.eq(SysRoleMenu::getDeleteStatus, sysRoleMenu.getDeleteStatus());
        }
        return queryWrapper;
    }

}
